﻿using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Web.Mvc.Html;
using System.Web.Routing;
using Kratos.Framework.Extensions.RouteExtensions;
using Kratos.Framework.Infrastructures;

namespace Kratos.Framework.Extensions.HtmlHelperExtensions
{
    public class KratosPage
    {
        private readonly AjaxHelper _ajaxHelper;
        private readonly HtmlHelper _htmlHelper;
        private readonly IPage _pager;
        private readonly string _action;
        private readonly string _controller;
        private readonly StringBuilder _pageBuilder = new StringBuilder();
        //显示的总长度
        private readonly int _showNumbers;
        //当前索引页前面显示的长度
        private readonly int _showStep;
        private readonly AjaxOptions _container2BeUpdated;
        private readonly bool _ajaxPage;

        public KratosPage(AjaxHelper ajaxHelper, IPage pager, string action, string controller, AjaxOptions options)
            : this(ajaxHelper, pager, action, controller, options, 10, 5) { }

        public KratosPage(AjaxHelper ajaxHelper, IPage pager, string action, string controller, AjaxOptions options, int showNumbers, int step = 5)
        {
            _ajaxHelper = ajaxHelper;
            _pager = pager;
            _action = action;
            _controller = controller;
            _container2BeUpdated = options;
            _showNumbers = showNumbers;
            _showStep = step;
            _ajaxPage = true;
        }

        public KratosPage(HtmlHelper htmlHelper, IPage pager, string action, string controller)
            : this(htmlHelper, pager, action, controller, 10, 5) { }

        public KratosPage(HtmlHelper htmlHelper, IPage pager, string action, string controller, int showNumbers, int step = 5)
        {
            _htmlHelper = htmlHelper;
            _pager = pager;
            _action = action;
            _controller = controller;
            _showNumbers = showNumbers;
            _showStep = step;
            _ajaxPage = false;
        }

        public string Render()
        {
            if (_pager == null)
                return "";

            _pageBuilder.Append("<div class=\"page\">");

            if (_pager.CurrentPageIndex > 0)
                _pageBuilder.Append(WriteLink(0, "first", "first"));

            if (_pager.IsPreviousPage)
                _pageBuilder.Append(WriteLink(_pager.CurrentPageIndex - 1, "<<prev", "prev"));

            int startIndex = _pager.CurrentPageIndex - _showStep <= 0 ? 0 : _pager.CurrentPageIndex - _showStep;
            int endIndex = startIndex + _showNumbers - 1;

            if (endIndex >= _pager.NumberOfPages - 1) endIndex = _pager.NumberOfPages - 1;

            if (endIndex - startIndex < _showNumbers - 1)
                startIndex = endIndex - _showNumbers + 1 > 0 ? endIndex - _showNumbers + 1 : 0;

            for (int i = startIndex; i <= endIndex; i++)
            {
                _pageBuilder.Append(WriteLink(i));
            }

            if (_pager.IsNextPage)
                _pageBuilder.Append(WriteLink(_pager.CurrentPageIndex + 1, "next>>", "next"));

            if (_pager.CurrentPageIndex + 1 < _pager.NumberOfPages)
                _pageBuilder.Append(WriteLink(_pager.NumberOfPages - 1, "last", "last"));

            _pageBuilder.Append("</div>");

            return _pageBuilder.ToString();
        }

        private string WriteLink(int pageIndex)
        {
            return WriteLink(pageIndex, (pageIndex + 1).ToString(CultureInfo.InvariantCulture));
        }

        private string WriteLink(int pageIndex, string linkText)
        {
            var dic = new Dictionary<string, object>();
            //string styles = "jquery-button ";
            if (_pager.CurrentPageIndex == pageIndex)
                //styles += "current-page";
                dic["class"] = "current-page";

            return _ajaxPage ? _ajaxHelper.ActionLink("{0}".With(linkText), _action, _controller, GenerateByPage(pageIndex), _container2BeUpdated, dic).ToString()
                                     : _htmlHelper.ActionLink("{0}".With(linkText), _action, _controller, GenerateByPage(pageIndex), dic).ToString();
        }

        private string WriteLink(int pageIndex, string linkText, string id)
        {
            var dic = new Dictionary<string, object>();
            dic["id"] = id;
            return _ajaxPage ? _ajaxHelper.ActionLink("{0}".With(linkText), _action, _controller, GenerateByPage(pageIndex), _container2BeUpdated, dic).ToString()
                : _htmlHelper.ActionLink("{0}".With(linkText), _action, _controller, GenerateByPage(pageIndex), dic).ToString();
        }

        private RouteValueDictionary GenerateByPage(int pageIndex)
        {
            var values = _ajaxPage ? _ajaxHelper.ViewContext.HttpContext.Request.GetRouteValue("p")
                                              : _htmlHelper.ViewContext.HttpContext.Request.GetRouteValue("p");
            values.Add("p", pageIndex + 1);

            return values;
        }
    }
}
